package es.ise.core.mbg.plugins;

import java.util.List;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;

/**
 * Este plugin hace que todas los mappers tengan dos versiones de cualquier
 * método select, una con RowBounds y otra sin ella, aptas para la paginación.
 * 
 * @author Paco
 *
 */
public class PagingEnabledClientsPlugin extends PluginAdapter
{
	/**
	 * {@inheritDoc}
	 * 
	 * @return siempre devuelve <code>true</code> porque no hay comprobaciones que hacer
	 */
	
	private static final FullyQualifiedJavaType rowBoundsType = new FullyQualifiedJavaType("org.apache.ibatis.session.RowBounds");
	
	@Override
	public boolean validate(List<String> warnings)
	{
		// no validations needed
		return true;
	}
	
	private Method cloneMethod(Method method)
	{
		Method copy = new Method();
		copy.setConstructor(method.isConstructor());
		copy.setFinal(method.isFinal());
		copy.setName(method.getName());
		copy.setReturnType(method.getReturnType());
		copy.setStatic(method.isStatic());
		copy.setVisibility(method.getVisibility());
		for(String annotation: method.getAnnotations())
			copy.addAnnotation(annotation);
		copy.addBodyLines(method.getBodyLines());
		for(FullyQualifiedJavaType exception: method.getExceptions())
			copy.addException(exception);
		for(String javaDocLine: method.getJavaDocLines())
			copy.addJavaDocLine(javaDocLine);
		for(Parameter parameter: method.getParameters())
			copy.addParameter(parameter);
		return copy;
	}
	
	private Method methodWithBoundParameter(Method method)
	{
		method.addParameter(new Parameter(rowBoundsType, "bounds"));
		return method;
	}

	@Override
	public boolean clientSelectByExampleWithBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable)
	{
		interfaze.addImportedType(rowBoundsType);
		interfaze.addMethod(methodWithBoundParameter(cloneMethod(method)));
		return true;
	}

	@Override
	public boolean clientSelectByExampleWithBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable)
	{
		topLevelClass.addImportedType(rowBoundsType);
		topLevelClass.addMethod(methodWithBoundParameter(cloneMethod(method)));
		return true;
	}

	@Override
	public boolean clientSelectByExampleWithoutBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable)
	{
		interfaze.addImportedType(rowBoundsType);
		interfaze.addMethod(methodWithBoundParameter(cloneMethod(method)));
		return true;
	}

	@Override
	public boolean clientSelectByExampleWithoutBLOBsMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable)
	{
		topLevelClass.addImportedType(rowBoundsType);
		topLevelClass.addMethod(methodWithBoundParameter(cloneMethod(method)));
		return true;
	}

	@Override
	public boolean clientSelectByPrimaryKeyMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable)
	{
		interfaze.addImportedType(rowBoundsType);
		interfaze.addMethod(methodWithBoundParameter(cloneMethod(method)));
		return true;
	}

	@Override
	public boolean clientSelectByPrimaryKeyMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedTable introspectedTable)
	{
		topLevelClass.addImportedType(rowBoundsType);
		topLevelClass.addMethod(methodWithBoundParameter(cloneMethod(method)));
		return true;
	}

	

}
